package gui;

import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Arrays;
import java.util.HashMap;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

import utils.math_utils.RandStream;
import utils.math_utils.RandStream.Rand;


@SuppressWarnings("serial")
class RandomizerPanel extends JPanel {

	private BoxLayout layout;
	
	private JLabel meanL = new JLabel("Mean:");
	private JLabel sdL = new JLabel("Std:");
	private JLabel maxL = new JLabel("Max:");
	private JLabel minL = new JLabel("Min:");
	private JLabel clipL = new JLabel("Clipping:");
	private HashMap<String, Rand> cbMappings =
			new HashMap<String, Rand>();	
		{ 	
			cbMappings.put("gaussian", Rand.GAUSS);
			cbMappings.put("uniform", Rand.UNIFORM);
			cbMappings.put("lognormal", Rand.LOGNORMAL);
		}
	private JPanel top;
	private JPanel middle;
	private JPanel bottom;
		
	private JTextField mean = new JTextField(5);
	private JTextField sd = new JTextField(5);
	private JTextField min = new JTextField(5);
	private JTextField max = new JTextField(5);
	private JCheckBox clipping = new JCheckBox();
	@SuppressWarnings({ "rawtypes", "unchecked" })
	private JComboBox randType =
			new JComboBox(Arrays.copyOf(cbMappings.keySet().toArray(),
			cbMappings.size(), String[].class));

	private RandStream rs;
	
	public RandomizerPanel (RandStream rs) {
		this.rs = rs;
		layout = new BoxLayout(this, BoxLayout.Y_AXIS);
		this.setLayout(layout);
		fillFieldValues();
		initializeLayout();
		addActionListeners();
		this.repaint();
	}
	
	public void fillFieldValues (){
		if(rs.getrType() == Rand.GAUSS) {
			randType.setSelectedItem("gaussian");
		} else if (rs.getrType() == Rand.UNIFORM) {
			randType.setSelectedItem("uniform");
			mean.setEnabled(false);
			sd.setEnabled(false);
			clipping.setSelected(true);
			clipping.setEnabled(false);
		} else {
			randType.setSelectedItem("lognormal");
		}
		mean.setText(((Double) rs.getMean()).toString());
		sd.setText(((Double) rs.getSigma()).toString());
		
		min.setText(((Double) rs.getMin()).toString());
		clipping.setSelected(rs.isClipping());
		if(!rs.isClipping()) {
			max.setEnabled(false);
			min.setEnabled(false);
		}	
		
		if(rs.getMax() == Double.MAX_VALUE) {
			max.setText("N/A");
		} else {
			max.setText(((Double) rs.getMax()).toString());
		}
	}
	
	
	public void initializeLayout () {
		
		FlowLayout lay = new FlowLayout();
		lay.setAlignment(FlowLayout.TRAILING);
		top = new JPanel();
		top.setLayout(lay);
		top.add(randType);
		top.add(Box.createHorizontalStrut(10));
		top.add(clipL);
		top.add(clipping);
		
		middle = new JPanel();
		lay = new FlowLayout();
		lay.setAlignment(FlowLayout.TRAILING);
		middle.setLayout(lay);
		middle.add(meanL);
		middle.add(mean);
		middle.add(sdL);
		middle.add(sd);
		
		bottom = new JPanel();
		lay = new FlowLayout();
		lay.setAlignment(FlowLayout.TRAILING);
		bottom.setLayout(lay);
		bottom.add(maxL);
		bottom.add(max);
		bottom.add(minL);
		bottom.add(min);
		
		this.add(top);
		this.add(middle);
		this.add(bottom);
	
	}
	
	public void addActionListeners() {
		
		randType.addActionListener(new ActionListener(){

			@Override
			public void actionPerformed(ActionEvent arg0) {
				if(cbMappings.get(randType.getSelectedItem()) == Rand.GAUSS) {
					if(!mean.isEnabled()) {
						mean.setEnabled(true);
					}
					if(!sd.isEnabled()){
						sd.setEnabled(true);
					}
					clipping.setEnabled(true);
				} else if (cbMappings.get(randType.getSelectedItem()) == Rand.UNIFORM) {
					randType.setSelectedItem("uniform");
					mean.setEnabled(false);
					sd.setEnabled(false);
					clipping.setSelected(true);
					clipping.setEnabled(false);
					if(!max.isEnabled()) {
						max.setEnabled(true);
					}
					if(!min.isEnabled()){
						min.setEnabled(true);
					}
				} else {
					if(!mean.isEnabled()) {
						mean.setEnabled(true);
					}
					if(!sd.isEnabled()){
						sd.setEnabled(true);
					}
					clipping.setEnabled(true);
				}
				
			}
			
		});
		
		clipping.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				if(clipping.isSelected()) {
					if(!max.isEnabled())
						max.setEnabled(true);
					if(!min.isEnabled())
						min.setEnabled(true);
				} else {
					if(max.isEnabled())
						max.setEnabled(false);
					if(min.isEnabled())
						min.setEnabled(false);
				}
				
			}
			
		});
		
	}

	public RandStream closeDialogOk(){
		rs = new RandStream();
		rs.setrType(cbMappings.get(randType.getSelectedItem()));
		rs.setClipping(clipping.isSelected());
		rs.setMean(Double.parseDouble(mean.getText()));
		rs.setSigma(Double.parseDouble(sd.getText()));
		try {
			rs.setMax(Double.parseDouble(max.getText()));
		} catch (NumberFormatException nfe) {
			rs.setMax(Double.MAX_VALUE);
		}
		rs.setMin(Double.parseDouble(min.getText()));	
		return rs;	
	}
	
	public void disablePanel(){
		super.setEnabled(false);
		for(Component c : getComponents()) {
			c.setEnabled(false);
			if(c instanceof JPanel){
				for(Component cSub : ((JPanel)c).getComponents()) {
					cSub.setEnabled(false);
				}
			}
		}
	}

	public RandomizerPanel enablePanel(){
		super.setEnabled(true);
		for(Component c : getComponents()) {
			c.setEnabled(true);
			if(c instanceof JPanel){
				for(Component cSub : ((JPanel)c).getComponents()) {
					cSub.setEnabled(true);
				}
			}
		}
		closeDialogOk();
		clipping.getActionListeners()[0].actionPerformed(null);
		randType.getActionListeners()[0].actionPerformed(null);
		return new RandomizerPanel(rs);
	}
	
}